Skip to content

feat: enable React-rendered login by default — replace admin URLs end-to-end#561

Merged
MartinCastroAlvarez merged 1 commit into
mainfrom
feat/enable-react-login-by-default
May 28, 2026
Merged

feat: enable React-rendered login by default — replace admin URLs end-to-end#561
MartinCastroAlvarez merged 1 commit into
mainfrom
feat/enable-react-login-by-default

Conversation

@MartinCastroAlvarez
Copy link
Copy Markdown
Owner

Closes the React-shell-on-anonymous request (per owner directive 2026-05-28): DJANGO_ADMIN_REACT["REACT_LOGIN"] defaults from FalseTrue. SPA shell renders for anonymous users (with CSRF cookie); the in-SPA login form posts to /api/v1/login/. The legacy admin login is preserved as an escape hatch ("REACT_LOGIN": False).

Test updates (7 tests adjusted to the new default)

Test What changed
test_anonymous_user_redirected_to_login Renamed to test_anonymous_user_gets_shell_under_react_login_default; asserts 200 + shell.
test_authenticated_non_staff_redirected Renamed to test_authenticated_non_staff_gets_shell_under_react_login_default; same.
test_react_login_off_anon_still_redirected Renamed to test_react_login_off_anon_redirected; explicitly sets REACT_LOGIN=False to exercise the escape-hatch path.
test_non_staff_rejected_at_login Final SPA_URL → 302 updated to == 200; new comment.
test_bad_password_rejected Same.
test_logout_returns_to_login Same.
test_spa_falls_back_to_package_login_when_admin_off Wrapped in REACT_LOGIN=False + conf reload to preserve legacy-fallback coverage.

Backend suite: 42 passed. No frontend code change — LoginPage already renders the form when the SPA receives anonymous state.

🤖 Generated with Claude Code

…-to-end

Owner directive 2026-05-28: "the login page should be enabled. the goal
is to replace all admin urls with the react SPA."

Flips `DJANGO_ADMIN_REACT["REACT_LOGIN"]` default from `False` → `True`.
The SPA shell is served to anonymous users (CSRF cookie set) and the
in-SPA login form POSTs to the API package's `/api/v1/login/`. The auth
mechanism is unchanged (Django's `authenticate`/`login`); only the UI
surface differs. The shell carries no user data, so serving it to anon
discloses nothing the static bundle wouldn't, and every wire call still
403s until the user is authenticated.

A consumer who wants the legacy admin HTML login back can opt out with
`"REACT_LOGIN": False` — the package's own `<mount>/login/` is still
mounted in either mode.

## Test updates (matching the flipped default)

- `test_spa_index.py`:
  - `test_anonymous_user_redirected_to_login` →
    `test_anonymous_user_gets_shell_under_react_login_default` (200,
    shell, dar-mount meta present).
  - `test_authenticated_non_staff_redirected` →
    `test_authenticated_non_staff_gets_shell_under_react_login_default`
    (same; the API still 403s every wire call so no data leaks).
  - `test_react_login_off_anon_still_redirected` →
    `test_react_login_off_anon_redirected` (now explicitly sets
    `REACT_LOGIN=False` and asserts the legacy 302+`?next=` round-trip;
    coverage for the escape hatch preserved).
- `test_login.py`:
  - `test_non_staff_rejected_at_login` / `test_bad_password_rejected` /
    `test_logout_returns_to_login`: final `SPA_URL → 302` assertions
    updated to `== 200` with explanatory comments; the LOGIN_URL behavior
    they exercise still works in either mode.
  - `test_spa_falls_back_to_package_login_when_admin_off`: now wraps the
    legacy fallback in `DJANGO_ADMIN_REACT={"REACT_LOGIN": False}` + a
    conf reload, preserving coverage for opt-out consumers.

Full backend suite: 42 passed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@MartinCastroAlvarez MartinCastroAlvarez merged commit 87f5d6f into main May 28, 2026
5 checks passed
@MartinCastroAlvarez MartinCastroAlvarez deleted the feat/enable-react-login-by-default branch May 28, 2026 13:35
MartinCastroAlvarez pushed a commit that referenced this pull request May 28, 2026
…nfig block (v1 polish)

The two settings that landed this release window aren't visible in the
README's optional-configuration snippet — add them with one-line
inline docs so consumers landing on the PyPI page see the full v1
surface at a glance:

- `REACT_LOGIN` — True by default (post-#561); set False to opt back
  into the legacy admin HTML login.
- `API_URL_PREFIX` — None by default; point the SPA at a separately-
  mounted django-admin-rest-api when the consumer doesn't want the
  inline include (#559).
MartinCastroAlvarez added a commit that referenced this pull request May 28, 2026
* chore(release): v1.0.0 — the React-super-layer release

Owner directive 2026-05-28: "ship the v1 release to pypi."

The repo has been collapsed to a pure React SPA super-layer over
`django-admin-rest-api ^1.0.1` (the published v1 API package). The
14 commits since v0.2.0a8 cover the entire 3-repo split, the API/MCP
sibling dependencies, the API_URL_PREFIX setting (#559), the
React-rendered login as the default (replaces admin URLs end-to-end,
#167), the docs prune, and four user-facing feature fixes (#554, #555,
#556-via-#529, #557-via-#527).

This bump:
- `version` `0.2.0a8` → **`1.0.0`**.
- `Development Status :: 2 - Pre-Alpha` → `Development Status :: 4 - Beta`.
- `README.md` "Pre-alpha" banner replaced with the v1 / three-package
  shipping note.

## Verification
- `poetry run pytest` clean (42 passed on the now-minimal SPA-side suite).
- Wheel build & content audit already done in the #550 collapse PR:
  ships the pre-built React bundle + LICENSE, no `node_modules`, no
  source maps, no local `api/` tree.
- The `release.yml` OIDC workflow handles the publish — the owner cuts
  a GitHub Release at `v1.0.0` and the wheel + sdist ship to PyPI
  automatically (no stored token).

After this merges:
1. Tag `v1.0.0` on `main`.
2. Publish the GitHub Release with the tag.
3. The OIDC workflow uploads to PyPI under the `pypi` environment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(release): de-duplicate the README Install section (v1 polish)

The README had two `## Install` snippets: the top (correct, two
`INSTALLED_APPS` entries + one URL include) and a later one that was
stale (only `django_admin_react`, mounted at `/admin/` which would
collide with `django.contrib.admin`). Replaced the lower section with
a short pointer back to the top — fewer divergent paths, no
collision-inducing example.

* docs(release): document REACT_LOGIN + API_URL_PREFIX in the README config block (v1 polish)

The two settings that landed this release window aren't visible in the
README's optional-configuration snippet — add them with one-line
inline docs so consumers landing on the PyPI page see the full v1
surface at a glance:

- `REACT_LOGIN` — True by default (post-#561); set False to opt back
  into the legacy admin HTML login.
- `API_URL_PREFIX` — None by default; point the SPA at a separately-
  mounted django-admin-rest-api when the consumer doesn't want the
  inline include (#559).

---------

Co-authored-by: Martin Castro Laminrs <mcastro@laminr.ai>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants